<template>
    <div class="typography-editor">
        <!-- 左侧预览区 -->
        <div class="panel preview">
            <h2>

                预览（点击组件选中）
            </h2>
            <div class="render-area">
                <template v-for="(block, index) in schema" :key="block.id">
                    <!-- 标题 -->
                    <t-typography-title v-if="block.type === 'title'" :level="block.props.level" :style="block.style"
                        class="preview-item" @click="selectComponent(index)">
                        {{ block.text || '标题' }}
                    </t-typography-title>

                    <!-- 内联文本 -->
                    <t-typography-text v-else-if="block.type === 'text' && !block.newLine" v-bind="block.props"
                        :style="block.style" class="preview-item inline-text" @click="selectComponent(index)">
                        {{ block.text || '文本' }}
                    </t-typography-text>

                    <!-- 换行文本块 -->
                    <div v-else-if="block.type === 'text' && block.newLine" class="text-block">
                        <t-typography-text v-bind="block.props" :style="block.style" class="preview-item"
                            @click="selectComponent(index)">
                            {{ block.text || '文本' }}
                        </t-typography-text>
                    </div>

                    <!-- 段落 -->
                    <t-typography-paragraph v-else-if="block.type === 'paragraph'" v-bind="block.props"
                        :style="block.style" class="preview-item" @click="selectComponent(index)">
                        {{ block.text || defaultParagraphText }}
                    </t-typography-paragraph>

                    <!-- 图片 -->
                    <div v-else-if="block.type === 'image'" class="preview-item image-wrapper"
                        :class="`align-${block.props.align}`" @click="selectComponent(index)">
                        <img :src="block.props.src" :alt="block.props.alt || '图片'" :style="{ width: block.props.width }"
                            @error="onImageError" />
                    </div>

                    <!-- 分割线 -->
                    <t-divider v-else-if="block.type === 'divider'" layout="horizontal" class="preview-item divider"
                        @click="selectComponent(index)" />
                </template>

                <!-- 空状态 -->
                <p v-if="schema.length === 0" class="empty">
                    <t-icon name="empty" size="24" style="color: #999" />
                    请在右侧添加组件
                </p>
            </div>
        </div>

        <!-- 右侧控制区 -->
        <div class="panel control">
            <h2>
                <t-icon name="edit-1" size="20" />
                编辑器
            </h2>

            <!-- 添加组件按钮 -->
            <t-space :size="10" style="margin-bottom: 20px">
                <t-button theme="primary" variant="outline" size="small" @click="addTitle">
                    标题
                </t-button>
                <t-button theme="primary" variant="outline" size="small" @click="addText">
                    文本
                </t-button>
                <t-button theme="primary" variant="outline" size="small" @click="addParagraph">
                    段落
                </t-button>
                <t-button theme="primary" variant="outline" size="small" @click="addImage">
                    图片
                </t-button>
                <t-button theme="primary" variant="outline" size="small" @click="addDivider">
                    分割线
                </t-button>
            </t-space>

            <!-- 组件列表 -->
            <div class="component-list">
                <div v-for="(block, idx) in schema" :key="block.id" class="component-item"
                    :class="{ active: selectedIndex === idx }" @click="selectComponent(idx)">
                    <t-icon :name="getIconName(block.type)" size="16" />
                    [{{ block.type }}]
                    {{ truncate(block.text || block.props?.src?.split('/').pop() || '内容', 10) }}
                    <t-button size="small" theme="danger" variant="text" @click.stop="removeComponent(idx)">
                        删除
                    </t-button>
                </div>
            </div>

            <!-- 属性面板 -->
            <div v-if="selectedComponent" class="property-panel">
                <h3>属性设置</h3>

                <!-- 通用文本 -->
                <!-- <t-textarea v-if="selectedComponent.text !== 'text'" v-model="selectedComponent.text" label="显示文本"
                    size="small" placeholder="请输入文本" /> -->

                <!-- 段落内容 -->
                <t-textarea v-if="selectedComponent.type === 'paragraph' || 'text'" v-model="selectedComponent.text"
                    label="段落内容" :autosize="{ minRows: 3, maxRows: 6 }" size="small" placeholder="请输入内容..." />

                <!-- 图片 URL -->
                <t-input v-if="selectedComponent.type === 'image'" v-model="selectedComponent.props.src" label="图片 URL"
                    size="small" placeholder="https://" />

                <!-- 图片对齐 -->
                <t-radio-group v-if="selectedComponent.type === 'image'" v-model="selectedComponent.props.align"
                    label="对齐方式" size="small">
                    <t-radio value="left">左对齐</t-radio>
                    <t-radio value="center">居中</t-radio>
                    <t-radio value="right">右对齐</t-radio>
                </t-radio-group>

                <!-- 图片宽度 -->
                <t-input v-if="selectedComponent.type === 'image'" v-model="selectedComponent.props.width" label="图片宽度"
                    size="small" placeholder="如：200px 或 50%"
                    @change="() => selectedComponent && normalizeWidth(selectedComponent.props)" />

                <!-- 标题级别 -->
                <t-select class="title-select" v-if="selectedComponent.type === 'title'"
                    v-model="selectedComponent.props.level" label="标题级别" size="small">
                    <t-option value="h1">H1</t-option>
                    <t-option value="h2">H2</t-option>
                    <t-option value="h3">H3</t-option>
                    <t-option value="h4">H4</t-option>
                    <t-option value="h5">H5</t-option>
                    <t-option value="h6">H6</t-option>
                </t-select>

                <!-- 文本主题 -->
                <t-select v-if="selectedComponent.type === 'text'" v-model="selectedComponent.props.theme" label="文本主题"
                    size="small" clearable>
                    <t-option value="primary">Primary</t-option>
                    <t-option value="success">Success</t-option>
                    <t-option value="warning">Warning</t-option>
                    <t-option value="error">Error</t-option>
                    <t-option value="secondary">Secondary</t-option>
                </t-select>

                <!-- 文本样式图标组 -->
                <div v-if="selectedComponent.type === 'text'" class="icon-toggle-group">
                    <h3>文本样式</h3>
                    <t-space size="small">
                        <t-tooltip content="加粗">
                            <t-icon name="textformat-bold" size="18" :class="{ active: selectedComponent.props.strong }"
                                @click="toggleProp('strong')" />
                        </t-tooltip>
                        <t-tooltip content="斜体">
                            <t-icon name="textformat-italic" size="18"
                                :class="{ active: selectedComponent.props.italic }" @click="toggleProp('italic')" />
                        </t-tooltip>
                        <t-tooltip content="高亮">
                            <t-icon name="highlight-1" size="18" :class="{ active: selectedComponent.props.mark }"
                                @click="toggleProp('mark')" />
                        </t-tooltip>
                        <t-tooltip content="下划线">
                            <t-icon name="textformat-underline" size="18"
                                :class="{ active: selectedComponent.props.underline }"
                                @click="toggleProp('underline')" />
                        </t-tooltip>
                        <t-tooltip content="删除线">
                            <t-icon name="textformat-strikethrough" size="18"
                                :class="{ active: selectedComponent.props.delete }" @click="toggleProp('delete')" />
                        </t-tooltip>
                        <t-tooltip content="可复制">
                            <t-icon name="copy" size="18" :class="{ active: selectedComponent.props.copyable }"
                                @click="toggleProp('copyable')" />
                        </t-tooltip>
                        <t-tooltip content="可编辑">
                            <t-icon name="edit-1" size="18" :class="{ active: selectedComponent.props.editable }"
                                @click="toggleProp('editable')" />
                        </t-tooltip>
                    </t-space>
                </div>

                <!-- 换行控制 -->
                <t-switch v-if="selectedComponent.type === 'text'" v-model="selectedComponent.newLine" label="换行显示"
                    size="small" />

                <!-- 段落省略 -->
                <t-switch v-if="selectedComponent.type === 'paragraph'" v-model="selectedComponent.props.ellipsis"
                    label="省略显示" size="small" />
            </div>

            <!-- 导入导出 -->
            <div class="io-tools">
                <t-space :size="10">
                    <t-button theme="default" size="small" @click="exportSchema">
                        <t-icon name="download" size="16" /> 导出 JSON
                    </t-button>
                    <t-button theme="default" size="small" @click="importSchema">
                        <t-icon name="upload" size="16" /> 导入 JSON
                    </t-button>
                </t-space>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { Icon as TIcon } from 'tdesign-icons-vue-next';

// 默认段落文本
const defaultParagraphText = 'TDesign 是一个企业级设计体系，支持多端、多框架、主题化开发...';

// 生成唯一 ID
const generateId = () => Date.now() + Math.random();

// 当前 schema 数据
const schema = ref<any[]>([]);

// 当前选中的组件索引
const selectedIndex = ref<number | null>(null);

// 计算当前选中组件
const selectedComponent = computed(() => {
    return selectedIndex.value !== null ? schema.value[selectedIndex.value] : null;
});

// 截取文本用于显示
const truncate = (str: string, len: number): string => {
    return str?.length > len ? str.slice(0, len) + '...' : str || '';
};

// 组件类型对应图标
const getIconName = (type: string): string => {
    const icons: Record<string, string> = {
        title: 'title',
        text: 'text',
        paragraph: 'align-left',
        image: 'image',
        divider: 'minus',
    };
    return icons[type] || 'component';
};

// 选择组件
const selectComponent = (index: number) => {
    selectedIndex.value = index;
};

// 删除组件
const removeComponent = (index: number) => {
    schema.value.splice(index, 1);
    if (selectedIndex.value === index) {
        selectedIndex.value = schema.value.length > 0 ? Math.min(index, schema.value.length - 1) : null;
    }
};

// 添加组件函数
const addTitle = () => {
    const block = {
        id: generateId(),
        type: 'title',
        text: '',
        props: { level: 'h3' },
        style: {},
    };
    schema.value.push(block);
    selectComponent(schema.value.length - 1);
};

const addText = () => {
    const block = {
        id: generateId(),
        type: 'text',
        text: '',
        props: { theme: 'primary' },
        newLine: false,
        style: {},
    };
    schema.value.push(block);
    selectComponent(schema.value.length - 1);
};

const addParagraph = () => {
    const block = {
        id: generateId(),
        type: 'paragraph',
        text: '',
        props: { ellipsis: true },
        style: {},
    };
    schema.value.push(block);
    selectComponent(schema.value.length - 1);
};

const addImage = () => {
    const block = {
        id: generateId(),
        type: 'image',
        props: {
            src: '',
            align: 'center',
            width: '200px',
        },
        style: {},
    };
    schema.value.push(block);
    selectComponent(schema.value.length - 1);
};

const addDivider = () => {
    const block = {
        id: generateId(),
        type: 'divider',
        props: {},
        style: {},
    };
    schema.value.push(block);
    selectComponent(schema.value.length - 1);
};

// 图片加载失败兜底
const onImageError = (e: Event) => {
    const img = e.target as HTMLImageElement;
    img.src = 'https://via.placeholder.com/150?text=Image+Error';
    img.onerror = null;
};

// 规范化宽度输入（修复 undefined.trim 错误）
const normalizeWidth = (props: any) => {
    // 安全检查
    if (!props || typeof props !== 'object') return;

    let w = props.width;
    if (!w || typeof w !== 'string') w = '200px';

    w = w.trim(); // 此时 w 一定是字符串
    if (!/%|px$/.test(w)) {
        w += 'px';
    }
    props.width = w;
};

// 切换属性（支持自动初始化 props）
const toggleProp = (prop: string) => {
    const comp = selectedComponent.value;
    if (!comp) return;

    if (!comp.props) comp.props = {};
    comp.props[prop] = !comp.props[prop];
};

// 导出 JSON
const exportSchema = () => {
    const dataStr = JSON.stringify(schema.value, null, 2);
    const blob = new Blob([dataStr], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'page-schema.json';
    a.click();
    URL.revokeObjectURL(url);
};

// 导入 JSON
const importSchema = () => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';
    input.onchange = (e: any) => {
        const file = e.target.files?.[0];
        if (!file) return;

        const reader = new FileReader();
        reader.onload = () => {
            try {
                const imported = JSON.parse(reader.result as string);

                // 初始化和修复数据
                const fixedData = imported.map((item: any) => {
                    if (!item.id) item.id = generateId();
                    if (item.type === 'image') {
                        item.props = item.props || {};
                        item.props.width = item.props.width || '200px';
                    }
                    if (!item.props) item.props = {};
                    if (!item.style) item.style = {};
                    return item;
                });

                schema.value = fixedData;
                selectedIndex.value = null;
            } catch (err) {
                alert('JSON 解析失败，请检查格式是否正确');
            }
        };
        reader.readAsText(file);
    };
    input.click();
};
</script>

<style lang="scss" scoped>
.typography-editor {
    display: flex;
    height: 100vh;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);
}

.panel {
    padding: 20px;
    border-radius: 12px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    overflow-y: auto;
}

.preview {
    flex: 1;
    background: #fff;
    margin: 16px 8px 16px 16px;
}

.control {
    width: 360px;
    background: #fff;
    margin: 5px;
    // border: 1px solid #e0e0e0;
}


.component-list {
    max-height: 220px;
    overflow-y: auto;
    margin-bottom: 20px;
    background: #fafafa;
    font-size: 14px;
}

.component-item {
    display: flex;
    align-items: flex-start;

    padding: 2px;
    border: 1px solid #eee;
    border-radius: 6px;
    cursor: pointer;
    background: #fff;
    transition: all 0.2s;
    font-family: 'Courier New', monospace;
    font-size: 13px;
}

.component-item:hover {
    border-color: #0052d9;
}

.component-item.active {
    border-color: #0052d9;
    background: #e8f3ff;
    font-weight: 500;
}

.component-item .t-icon {
    flex-shrink: 0;
}

.render-area {
    min-height: 300px;
    line-height: 1.7;
    padding: 10px 0;
}

.empty {
    text-align: center;
    color: #999;
    font-style: italic;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 40px 0;
}

.preview-item {
    cursor: pointer;
    user-select: none;
    transition: all 0.2s;
    padding: 2px 4px;
    border-radius: 4px;
}

.preview-item:hover {
    background: #f0f4ff;
}

.inline-text {
    margin: 0 6px;
}

.text-block {
    margin: 6px 0;
}

.divider {
    margin: 16px 0;
}

.image-wrapper {
    margin: 14px 0;

    &.align-left {
        text-align: left;
    }

    &.align-center {
        text-align: center;
    }

    &.align-right {
        text-align: right;
    }
}

.image-wrapper img {
    max-width: 100%;
    height: auto;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.property-panel {
    background: #f9f9f9;
    // border-radius: 8px;
    // border: 1px solid #eaeaea;
    margin-bottom: 5px;
    gap: 10px;
    display: flex;
    flex-direction: column;

}

// .property-panel h3 {
//     font-size: 16px;
//     margin-bottom: 12px;
//     color: #2c3e50;
// }

.icon-toggle-group {
    margin: 12px 0;
}

.icon-toggle-group label {
    display: block;
    margin-bottom: 6px;
    font-size: 14px;
    color: #333;
}

.icon-toggle-group .t-space .t-icon {
    padding: 4px;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;
    color: #666;
}

.icon-toggle-group .t-icon.active {
    color: #0052d9;
    background: #e8f3ff;
}

.io-tools {
    border-top: 1px dashed #ddd;
    padding-top: 16px;
}

:deep(.t-button__icon) {
    display: flex;
    align-items: center;
}
</style>